'''
Created on Feb 1, 2012

@author: xzhu
'''
import const

class CONF():
    '''
    MCCE CONF class
    only consider one titration point 
    '''

    initPH = 7.0                 # only consider the pH titration with initial pH 7.0
    initEh = 0
    
    vdwScale  = 0.1
    vdw0Scale = 0.1
    vdw1Scale = 0.1
    
    def __init__(self):
        '''
        Constructor
        '''
        # fields in "head3.lst"
        self.iConf = 0
        
        self.confID = ''         # THR01A0005_001
        self.resName = ''        # THR
        self.confType = ''       # THR01
        self.chainID = ''        # A
        self.reSeq = 0           # 5
        self.idInRes = 0         # 1
        self.resID = ''          # THRA0005
        
        self.FL = ''
        self.hocc = 0.0          # occupancy in head3.lst
        self.crg = 0.0
        self.Em0 = 0
        self.Pka0 = 0.0
        self.ne = 0
        self.nH = 0
        self.vdw0 = 0.0
        self.vdw1 = 0.0
        self.tors = 0.0
        self.epol = 0.0
        self.dsolv = 0.0
        self.extra = 0.0
        self.hist  = ''
        self.selfEner = 0.0
        
        self.focc = 0.0            # occupancy in fort.38 
        self.vPair = []
        self.ePair = []
        self.tPair = []
        
    def head3_init(self, hline):
        '''
        initialize the conformer state from head3.lst
        '''
        self.iConf = int(hline[:5]) - 1
        
        self.confID = hline[6:20]
        self.resName = self.confID[:3]
        self.confType = self.confID[:5]
        self.chainID = self.confID[5]
        self.reSeq   = int(self.confID[6:10])
        self.idInRes = int(self.confID[-3:])
        self.resID = self.confID[:3] + self.confID[5:10]
        
        self.FL = hline[21]
        self.hocc = float(hline[23:27])
        self.crg = float(hline[29:34])
        self.Em0 = int(hline[35:40])
        self.Pka0 = float(hline[41:46])
        self.ne = int(hline[47:49])
        self.nH = int(hline[50:52])
        self.vdw0 = float(hline[52:60]) * self.vdw0Scale
        self.vdw1 = float(hline[60:68]) * self.vdw1Scale
        self.tors = float(hline[68:76])
        self.epol = float(hline[76:84])
        self.dsolv = float(hline[84:92])
        self.extra = float(hline[92:100])
        self.hist = hline[101:112]
        
        if self.confID[3:5] == 'DM':
            self.selfEner = 0.0
        else:
            self.selfEner = self.vdw0 + self.vdw1 + self.tors + self.epol + self.dsolv + self.extra    \
                          + (CONF.initPH - self.Pka0) * self.nH * const.ph2Kcal                        \
                          + (CONF.initEh - self.Em0) * self.ne * const.mev2Kcal  
        #print self.confID, self.selfEner
        
    def fort_init(self, fline):
        '''
        initialize the occupancy from the fort.38 file
        '''        
        if fline[:14] == self.confID:
            fields = fline.split()
            self.focc = float(fields[1])
        #    for fl in fields:
        #        self.focc.append(float(fl))
                
    def ener_opp_init(self, efile):
        '''
        initialize the pairwise interaction energy from energy opp file
        '''
        for line in open(efile).readlines():
            self.ePair.append(float(line[20:29]))
            self.vPair.append(float(line[29:37]) * self.vdwScale) 
            self.tPair.append(float(line[20:29]) + float(line[29:37]) * self.vdwScale)
        #if self.iConf == 123:
        #    print self.confID
        #    for each_t in self.tPair:
        #        print each_t
            
    def is_in_res(self, residue):
        '''
        test if the conformer in the residue
        '''
        
        return self.resID == residue.resID
            
    def is_this_sign(self, sign):
        '''
        test if the confomrer is of sign ionization state
        '''
        
        return const.ION_HEAD[self.confID[3]] == sign           # sign: '0', '+', '-', 'D'
